package com.corn.juc.lock.ls;

import lombok.SneakyThrows;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.LockSupport;

/**
 * @author : Jim Wu
 * @version 1.0
 * @function :
 * @since : 2021/1/11 11:54
 */

public class LockSupportDemo {

    public static void main(String[] args) {
//        simpleLockSupport();
        unparkBeforePark();
    }

    /**
     * unpark必须在 线程启动之后调用 如果线程启动之前调用 unpark没有效果
     * unpark在线程启动之后先调用了 再调用park 可以正常解锁,因为unpark本质把permit改成了1 调用park正常消费
     */
    private static void unparkBeforePark() {
        Thread t1 = new Thread("A") {
            @SneakyThrows
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName() + " before park !");
                TimeUnit.SECONDS.sleep(3);
                LockSupport.park();
                System.out.println(Thread.currentThread().getName() + " after park !");
            }
        };
        // 线程启动之前先unpark 没有任何效果 park还是阻塞
//        LockSupport.unpark(t1);
        System.out.println("start");
        t1.start();
        // 线程启动之后 先调用unpark 线程里面park 可以正常执行完
        LockSupport.unpark(t1);
    }


    /**
     * lockSupport最基本的使用
     */
    private static void simpleLockSupport() {
        Thread t1 = new Thread("A") {
            @SneakyThrows
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName() + " 进入 !");
                LockSupport.park();
                System.out.println(Thread.currentThread().getName() + " 被唤醒 !");
            }
        };
        t1.start();
        Thread t2 = new Thread("B") {
            @SneakyThrows
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName() + " 进入 !");
                TimeUnit.SECONDS.sleep(5);
                LockSupport.unpark(t1);
                System.out.println(Thread.currentThread().getName() + " 唤醒 线程A !");
            }
        };
        t2.start();
    }
}
